package atag.runtime.ln.neighborhoodDefs;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;


import atag.runtime.ln.nodeAttributes.BooleanAttribute;
import atag.runtime.ln.nodeAttributes.NodeAttribute;

/**
 * An atomic predicate specifying a constraint on the value of a boolean
 * attribute. The possible constraints are defined as constants in this class.
 * 
 * @author Luca Mottola <a
 *         href="mailto:mottola@elet.polimi.it">mottola@elet.polimi.it</a>
 * 
 */
public class BooleanSimplePredicate extends Predicate {

	// Possible comparators
	public static final int NOT_EQUAL = 0;

	public static final int EQUAL = 1;

	// Predicate data
	private String attrName;

	private int comparator;

	private boolean value;

	/**
	 * Creates an instance of this predicate.
	 * 
	 * @param attrName
	 *            the name of the attribute the predicate refers to.
	 * @param comparator
	 *            the constraint selected.
	 * @param value
	 *            the boolean value to compare the attribute against.
	 */
	public BooleanSimplePredicate(String attrName, int comparator, boolean value) {

		this.attrName = attrName;
		this.comparator = comparator;
		this.value = value;
	}

	/**
	 * @see polimi.ln.neighborhoodDefs.AtomicPredicate#matches(polimi.ln.nodeAttributes.NodeAttribute)
	 */
	public boolean matches(NodeAttribute attr) {

		if (!(attr instanceof BooleanAttribute))
			return false;

		if (!attr.getKey().equals(attrName))
			return false;

		boolean attrValue = ((Boolean) attr.getValue()).booleanValue();

		switch (comparator) {

		case NOT_EQUAL:
			return (attrValue != value);
		case EQUAL:
			return (attrValue == value);
		default:
			return false;
		}
	}

	public String toString() {

		String msg = "BooleanSimple predicate for attribute " + attrName + " ";

		switch (comparator) {

		case EQUAL:
			msg = msg.concat(" equal ");
			break;
		case NOT_EQUAL:
			msg = msg.concat(" not equal ");
			break;

		default:
			msg = msg.concat("UNKNOWN");
			break;
		}

		return msg.concat(" " + value);
	}
	
	public DataOutput serialize(DataOutput dg) throws IOException {

		dg.writeByte(Predicate.BOOLEAN_SIMPLE);
		dg.writeUTF(attrName);
		dg.writeInt(comparator);
		dg.writeBoolean(value);

		return dg;
	}
	
	public static Predicate deserialize(DataInput dg) throws IOException {
		
		String serializedNameStr = dg.readUTF();
		int comparator = dg.readInt();
		boolean value = dg.readBoolean();
		
		return new BooleanSimplePredicate(serializedNameStr, comparator, value);
	}

}
